package com.xiang.community.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xiang.community.dao.DiscussPostMapper;
import com.xiang.community.dao.UserMapper;
import com.xiang.community.dao.elasticsearch.DiscussPostRepository;
import com.xiang.community.dto.PageResult;
import com.xiang.community.dto.ResultDTO;
import com.xiang.community.entity.DiscussPost;
import com.xiang.community.enums.ResponseCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class DiscussPostService {

    @Resource
    private DiscussPostMapper discussPostMapper;
    @Resource
    private DiscussPostRepository discussPostRepository;
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Resource
    private UserMapper userMapper;

    public PageInfo<DiscussPost> findDiscussPosts(int pageNum, int pageSize, Integer userId, String orderBy) {
        if (StringUtils.isNotBlank(orderBy)) {
            PageHelper.startPage(pageNum, pageSize, orderBy);
        } else {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<DiscussPost> list = discussPostMapper.selectDiscussPosts(userId);
        PageInfo<DiscussPost> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    public ResultDTO saveDiscussPost(DiscussPost discussPost) {
        discussPostMapper.save(discussPost);
        // 存入ES
        discussPostRepository.save(discussPost);
        return ResultDTO.builder().code(ResponseCodeEnum.SUCCESS.getCode()).build();
    }

    public DiscussPost findOne(int postId) {
        return discussPostMapper.selectDiscussPost(postId);
    }

    public void goodPost(Integer postId) {
        discussPostMapper.updateGood(postId);
    }

    public void updateValue(Integer postId, String field, Integer value) {
        discussPostMapper.updateValue(postId, field, value);
    }

    public void esSave(DiscussPost discussPost) {
        discussPostRepository.save(discussPost);
    }

    public PageResult searchDiscussPost(String keyWord, int pageSize, int pageNum) {
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery(keyWord, "title", "content"))
                .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                // 页码从0开始
                .withPageable(PageRequest.of(pageNum - 1, pageSize))
                .withHighlightFields(
                        new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
                        new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
                ).build();
        SearchHits<DiscussPost> searchHits = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);
        List<Map<String, Object>> discussPosts = new ArrayList<>(16);
        for (SearchHit<DiscussPost> searchHit : searchHits.getSearchHits()) {
            DiscussPost discussPost = searchHit.getContent();
            Map<String, Object> map = new HashMap<>(2);
            map.put("post", discussPost);
            map.put("user", userMapper.selectById(discussPost.getUserId()));
            discussPosts.add(map);
        }
        return PageResult.getInstance(searchHits.getTotalHits(), discussPosts);
    }

    public List<DiscussPost> findAll() {
        return discussPostMapper.selectAll();
    }
}
